﻿using System;
using System.Collections.Generic;
using ValidationFramework.Reflection;

namespace ValidationFramework
{
	public interface IValidationPolicy
	{
		/// <summary>
		/// The name of the member this policy is for
		/// </summary>
		string MemberName { get;  }

		/// <summary>
		/// Validates a property against the policy.
		/// </summary>
		/// <param name="parentValue">The value of the object containing the property to test</param>
		/// <param name="context">An arbitrary context defined by the consumer of the framework</param>
		/// <param name="ruleset">A filter to apply when testing rules.</param>
		/// <returns>A PropertyValidationError for every broken rule in the policy</returns>
		/// <exception cref="ArgumentNullException">row filter cannot be null</exception>
		List<ValidationError> Validate(object parentValue, ValidationOptions options);

		/// <summary>
		/// Checks the supplied value against this policies rules ignoring rules scoped at the parent level.
		/// </summary>
		/// <param name="memberValue">The value of the member being tested</param>
		/// <param name="context">An arbitrary context defined by the consumer of the framework</param>
		/// <param name="ruleset">A filter to apply when testing rules. If null all rules will be tested</param>
		/// <returns>A list of validation errors for all the rules that were broken</returns>
		/// <remarks>This is used in thin client scenarios when we can't guarantee access to the parent object being built/edited.</remarks>
		List<ValidationError> ValidateNoParent(object memberValue, ValidationOptions options);

		RuleCollection ParentScopeRules { get; }
		RuleCollection MemberScopeRules { get; }

		int RuleCount  { get; }

		/// <summary>
		/// Adds a rule to the validation policy
		/// </summary>
		/// <param name="rule"></param>
		/// <param name="scope"></param>
		Rule AddRule(Rule rule, RuleScope scope);

		//ICachedReflectionInfo MemberReflectionInfo { get; }

		/// <summary>
		/// Makes validation policy read only
		/// </summary>
		void Lock();

		/// <summary>
		/// Makes validation policy writable
		/// </summary>
		void UnLock();
	}
}
